<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 5.4.0">


  <link rel="apple-touch-icon" sizes="180x180" href="/images/favicon.ico">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon.ico">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon.ico">
  <link rel="mask-icon" href="/images/favicon.ico" color="#222">

<link rel="stylesheet" href="/css/main.css">



<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.15.4/css/all.min.css" integrity="sha256-mUZM63G8m73Mcidfrv5E+Y61y7a12O5mW4ezU3bxqW4=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/animate.css@3.1.1/animate.min.css" integrity="sha256-PR7ttpcvz8qrF57fur/yAx1qXMFJeJFiA6pSzWi0OIE=" crossorigin="anonymous">

<script class="next-config" data-name="main" type="application/json">{"hostname":"example.com","root":"/","images":"/images","scheme":"Muse","darkmode":false,"version":"8.8.0","exturl":false,"sidebar":{"position":"left","display":"remove","padding":18,"offset":12},"copycode":true,"bookmark":{"enable":false,"color":"#222","save":"auto"},"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"stickytabs":false,"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"prism":false,"i18n":{"placeholder":"搜索...","empty":"没有找到任何搜索结果：${query}","hits_time":"找到 ${hits} 个搜索结果（用时 ${time} 毫秒）","hits":"找到 ${hits} 个搜索结果"},"path":"/search.xml","localsearch":{"enable":"false;","trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false}}</script><script src="/js/config.js"></script>
<meta name="description" content="Ⅰ. 为什么需要Servlet1.1 Tomcat">
<meta property="og:type" content="article">
<meta property="og:title" content="Servlet，我还是爱你的">
<meta property="og:url" content="http://example.com/2021/09/04/Servlet%EF%BC%8C%E6%88%91%E8%BF%98%E6%98%AF%E7%88%B1%E4%BD%A0%E7%9A%84/index.html">
<meta property="og:site_name" content="ADGai&#39;s Blog">
<meta property="og:description" content="Ⅰ. 为什么需要Servlet1.1 Tomcat">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://gitee.com/AD-Gai-Code/pic-go/raw/master/image-20210410173843721.png">
<meta property="og:image" content="https://gitee.com/AD-Gai-Code/pic-go/raw/master/image-20210411005345135.png">
<meta property="og:image" content="https://gitee.com/AD-Gai-Code/pic-go/raw/master/image-20210412111221442.png">
<meta property="og:image" content="https://gitee.com/AD-Gai-Code/pic-go/raw/master/image-20210412113852585.png">
<meta property="og:image" content="https://gitee.com/AD-Gai-Code/pic-go/raw/master/image-20210412153202697.png">
<meta property="og:image" content="https://gitee.com/AD-Gai-Code/pic-go/raw/master/image-20210412160221386.png">
<meta property="og:image" content="https://gitee.com/AD-Gai-Code/pic-go/raw/master/image-20210412160730423.png">
<meta property="og:image" content="https://gitee.com/AD-Gai-Code/pic-go/raw/master/image-20210412165223986.png">
<meta property="og:image" content="https://gitee.com/AD-Gai-Code/pic-go/raw/master/image-20210412170344538.png">
<meta property="og:image" content="https://gitee.com/AD-Gai-Code/pic-go/raw/master/image-20210412171712463.png">
<meta property="og:image" content="https://gitee.com/AD-Gai-Code/pic-go/raw/master/image-20210412174417990.png">
<meta property="og:image" content="https://gitee.com/AD-Gai-Code/pic-go/raw/master/image-20210412174537456.png">
<meta property="article:published_time" content="2021-09-04T14:32:51.516Z">
<meta property="article:modified_time" content="2022-03-01T13:20:40.695Z">
<meta property="article:author" content="AiLaodu">
<meta property="article:tag" content="java基础">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://gitee.com/AD-Gai-Code/pic-go/raw/master/image-20210410173843721.png">


<link rel="canonical" href="http://example.com/2021/09/04/Servlet%EF%BC%8C%E6%88%91%E8%BF%98%E6%98%AF%E7%88%B1%E4%BD%A0%E7%9A%84/">



<script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":false,"isPost":true,"lang":"zh-CN","comments":true,"permalink":"http://example.com/2021/09/04/Servlet%EF%BC%8C%E6%88%91%E8%BF%98%E6%98%AF%E7%88%B1%E4%BD%A0%E7%9A%84/","path":"2021/09/04/Servlet，我还是爱你的/","title":"Servlet，我还是爱你的"}</script>

<script class="next-config" data-name="calendar" type="application/json">""</script>
<title>Servlet，我还是爱你的 | ADGai's Blog</title>
  




  <noscript>
    <link rel="stylesheet" href="/css/noscript.css">
  </noscript>
</head>

<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
  <div class="headband"></div>

  <main class="main">
    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏" role="button">
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <i class="logo-line"></i>
      <h1 class="site-title">ADGai's Blog</h1>
      <i class="logo-line"></i>
    </a>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
        <i class="fa fa-search fa-fw fa-lg"></i>
    </div>
  </div>
</div>



<nav class="site-nav">
  <ul class="main-menu menu">
        <li class="menu-item menu-item-home"><a href="/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a></li>
        <li class="menu-item menu-item-tags"><a href="/tags/" rel="section"><i class="fa fa-tags fa-fw"></i>标签</a></li>
        <li class="menu-item menu-item-categories"><a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类</a></li>
        <li class="menu-item menu-item-archives"><a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档</a></li>
      <li class="menu-item menu-item-search">
        <a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
        </a>
      </li>
  </ul>
</nav>



  <div class="search-pop-overlay">
    <div class="popup search-popup"><div class="search-header">
  <span class="search-icon">
    <i class="fa fa-search"></i>
  </span>
  <div class="search-input-container"></div>
  <span class="popup-btn-close" role="button">
    <i class="fa fa-times-circle"></i>
  </span>
</div>
<div class="search-result-container">
  <div class="algolia-stats"><hr></div>
  <div class="algolia-hits"></div>
  <div class="algolia-pagination"></div>
</div>

    </div>
  </div>

</div>
    </header>

    
  <div class="back-to-top" role="button" aria-label="返回顶部">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>

<noscript>
  <div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>


    <div class="main-inner post posts-expand">


  


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://example.com/2021/09/04/Servlet%EF%BC%8C%E6%88%91%E8%BF%98%E6%98%AF%E7%88%B1%E4%BD%A0%E7%9A%84/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="AiLaodu">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="ADGai's Blog">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          Servlet，我还是爱你的
        </h1>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2021-09-04 22:32:51" itemprop="dateCreated datePublished" datetime="2021-09-04T22:32:51+08:00">2021-09-04</time>
    </span>
      <span class="post-meta-item">
        <span class="post-meta-item-icon">
          <i class="far fa-calendar-check"></i>
        </span>
        <span class="post-meta-item-text">更新于</span>
        <time title="修改时间：2022-03-01 21:20:40" itemprop="dateModified" datetime="2022-03-01T21:20:40+08:00">2022-03-01</time>
      </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/java%E5%9F%BA%E7%A1%80/" itemprop="url" rel="index"><span itemprop="name">java基础</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
        <h2 id="Ⅰ-为什么需要Servlet"><a href="#Ⅰ-为什么需要Servlet" class="headerlink" title="Ⅰ. 为什么需要Servlet"></a>Ⅰ. 为什么需要Servlet</h2><h3 id="1-1-Tomcat"><a href="#1-1-Tomcat" class="headerlink" title="1.1 Tomcat"></a>1.1 Tomcat</h3><span id="more"></span>

<p>Tomcat是一个Web服务器（同时也是Servlet容器），通过它我们可以很方便地<strong>接收和返回</strong>到请求（如果不用Tomcat，那我们需要自己写Socket来接收和返回请求）。</p>
<h4 id="Tomcat的目录层次结构"><a href="#Tomcat的目录层次结构" class="headerlink" title="Tomcat的目录层次结构"></a>Tomcat的目录层次结构</h4><p><img src="https://gitee.com/AD-Gai-Code/pic-go/raw/master/image-20210410173843721.png" alt="image-20210410173843721"></p>
<h3 id="1-2-什么是Servlet？"><a href="#1-2-什么是Servlet？" class="headerlink" title="1.2 什么是Servlet？"></a>1.2 什么是Servlet？</h3><p>Servlet其实就是一个<strong>遵循Servlet开发的java类</strong>。Serlvet是<strong>由服务器调用的</strong>，<strong>运行在服务器端</strong>。我们编写java程序想要在网上实现聊天、发帖、这样的一些交互功能，<strong>普通的java技术是非常难完成的</strong>。于是sun公司就提供了Serlvet这种技术供我们使用。</p>
<h3 id="1-3-HTTP协议"><a href="#1-3-HTTP协议" class="headerlink" title="1.3 HTTP协议"></a>1.3 HTTP协议</h3><blockquote>
<p>超文本（HTML，css，JavaScript和图片等）传输协议（HTTP，HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议。所有的WWW文件都必须遵守这个标准。它是TCP/IP协议的一个<strong>应用层协议</strong></p>
</blockquote>
<p>直白的说，HTTP协议就是浏览器和服务器之间通讯的一种协议，就比如我们在点击网站链接打开一个网站的时候，浏览器会给服务器发送一段文本，告诉服务器自己打开的是哪一个网页，服务器收到请求以后，会返回给浏览器一段文本，浏览器解析后将其显示给用户。</p>
<h3 id="1-4-HTTP-请求"><a href="#1-4-HTTP-请求" class="headerlink" title="1.4 HTTP 请求"></a>1.4 HTTP 请求</h3><p><strong>浏览器向服务器请求某个web资源时，称之为浏览器向服务器发送了一个http请求。</strong></p>
<p>一个完整http请求应该包含三个部分：</p>
<ol>
<li>请求行【描述客户端的<strong>请求方式</strong>、<strong>请求的资源名称</strong>，以及使用的<strong>HTTP协议版本号</strong>（1.0和1.1）】</li>
<li>多个消息头【描述客户端请求哪台主机，以及<strong>客户端的一些环境信息</strong>等】</li>
<li>一个空行</li>
</ol>
<h4 id="请求行"><a href="#请求行" class="headerlink" title="请求行"></a>请求行</h4><p>请求行：GET /java.html HTTP/1.1</p>
<p><strong>请求行中的GET称之为请求方式</strong>，请求方式有：POST,GET,HEAD,OPTIONS,DELETE,TRACE,PUT。</p>
<p><strong>常用的有：POST,GET</strong></p>
<p>一般来说，当我们<strong>点击超链接，通过地址栏访问都是get请求方式</strong>。通过<strong>表单提交的数据一般是post方式</strong>。</p>
<p>可以简单理解<strong>GET方式用来查询数据</strong>,<strong>POST方式用来提交数据</strong>，<strong>get的提交速度比post快</strong></p>
<p>GET方式：在URL地址后<strong>附带的参数是有限制的</strong>，其<strong>数据容量通常不能超过1K</strong>。</p>
<p>POST方式：可以在<strong>请求的实体内容中向服务器发送数据</strong>，<strong>传送的数据量无限制</strong>。</p>
<h4 id="请求头"><a href="#请求头" class="headerlink" title="请求头"></a>请求头</h4><ul>
<li>Accept: text/html,image/* 【浏览器告诉服务器，它支持的数据类型】</li>
<li>Accept-Charset: ISO-8859-1 【浏览器告诉服务器，它支持哪种<strong>字符集</strong>】</li>
<li>Accept-Encoding: gzip,compress 【浏览器告诉服务器，它支持的<strong>压缩格式</strong>】</li>
<li>Accept-Language: en-us,zh-cn 【浏览器告诉服务器，它的语言环境】</li>
<li>Host: <a href="http://www.it315.org:80【浏览器告诉服务器，它的想访问哪台主机】">www.it315.org:80【浏览器告诉服务器，它的想访问哪台主机】</a></li>
<li>If-Modified-Since: Tue, 11 Jul 2000 18:23:51 GMT【浏览器告诉服务器，缓存数据的时间】</li>
<li>Referer: <a target="_blank" rel="noopener" href="http://www.it315.org/index.jsp%E3%80%90%E6%B5%8F%E8%A7%88%E5%99%A8%E5%91%8A%E8%AF%89%E6%9C%8D%E5%8A%A1%E5%99%A8%EF%BC%8C%E5%AE%A2%E6%88%B7%E6%9C%BA%E6%98%AF%E4%BB%8E%E9%82%A3%E4%B8%AA%E9%A1%B5%E9%9D%A2%E6%9D%A5%E7%9A%84---**%E5%8F%8D%E7%9B%97%E9%93%BE**%E3%80%91">http://www.it315.org/index.jsp【浏览器告诉服务器，客户机是从那个页面来的---**反盗链**】</a></li>
<li>8.User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)【浏览器告诉服务器，浏览器的内核是什么】</li>
<li>Cookie【浏览器告诉服务器，<strong>带来的Cookie是什么</strong>】</li>
<li>Connection: close/Keep-Alive 【浏览器告诉服务器，请求完后是断开链接还是保持链接】</li>
<li>Date: Tue, 11 Jul 2000 18:23:51 GMT【浏览器告诉服务器，请求的时间】</li>
</ul>
<h3 id="1-5-HTTP响应"><a href="#1-5-HTTP响应" class="headerlink" title="1.5 HTTP响应"></a>1.5 HTTP响应</h3><p>一个HTTP响应代表着<strong>服务器向浏览器回送数据</strong></p>
<p>一个完整的HTTP响应应该包含四个部分:</p>
<ol>
<li>一个状态行【用于描述<strong>服务器对请求的处理结果。</strong>】</li>
<li>多个消息头【用于描述<strong>服务器的基本信息</strong>，以及<strong>数据的描述</strong>，<strong>服务器通过这些数据的描述信息，可以通知客户端如何处理等一会儿它回送的数据</strong>】</li>
<li>一个空行</li>
<li>实体内容【<strong>服务器向客户端回送的数据</strong>】</li>
</ol>
<h4 id="状态行"><a href="#状态行" class="headerlink" title="状态行"></a>状态行</h4><p>格式： HTTP版本号　状态码　原因叙述</p>
<p>状态行：HTTP/1.1 200 OK</p>
<p>状态码用于表示<strong>服务器对请求的处理结果</strong>，它是一个<strong>三位的十进制数</strong>。响应状态码分为5类</p>
<p><img src="https://gitee.com/AD-Gai-Code/pic-go/raw/master/image-20210411005345135.png" alt="image-20210411005345135"></p>
<h2 id="Ⅱ-Servlet的作用"><a href="#Ⅱ-Servlet的作用" class="headerlink" title="Ⅱ. Servlet的作用"></a>Ⅱ. Servlet的作用</h2><p>Servlet带给我们最大的作用就是能够<strong>处理浏览器带来HTTP请求，并返回一个响应给浏览器，从而实现浏览器和服务器的交互</strong>。</p>
<p>简单来说，Servlet 就是运行在服务器上的一个 java 小程序，<strong>它可以接收客户端发送过来的请求，并响应数据给客户端。</strong></p>
<h3 id="实现Servlet"><a href="#实现Servlet" class="headerlink" title="实现Servlet"></a>实现Servlet</h3><p>1、编写一个类去实现 Servlet 接口  </p>
<p>2、实现 service 方法，处理请求，并响应数据 </p>
<p>3、到 web.xml 中去配置 servlet 程序的访问地址。</p>
<p>首先实现 Servlet 接口，我们发现有5个方法需要重写，</p>
<ul>
<li><p>init【初始化】，</p>
</li>
<li><p>destroy【销毁】,</p>
</li>
<li><p>service【服务】,</p>
</li>
<li><p>ServletConfig【Servlet配置】,</p>
</li>
<li><p>getServletInfo【Serlvet信息】</p>
</li>
</ul>
<p>发现service()方法是最有可能是写逻辑代码的地方。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">HelloServlet</span> <span class="keyword">implements</span> <span class="title">Servlet</span> </span>&#123;</span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">* service 方法是专门用来处理请求和响应的</span></span><br><span class="line"><span class="comment">* <span class="doctag">@param</span> servletRequest</span></span><br><span class="line"><span class="comment">* <span class="doctag">@param</span> servletResponse</span></span><br><span class="line"><span class="comment">* <span class="doctag">@throws</span> ServletException</span></span><br><span class="line"><span class="comment">* <span class="doctag">@throws</span> IOException</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">service</span><span class="params">(ServletRequest servletRequest, ServletResponse                                servletResponse)</span> <span class="keyword">throws</span> ServletException, IOException </span>&#123;</span><br><span class="line">		System.out.println(<span class="string">&quot;Hello Servlet 被访问了&quot;</span>);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>web.xml 中的配置：</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">web-app</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://xmlns.jcp.org/xml/ns/javaee&quot;</span></span></span><br><span class="line"><span class="tag">         <span class="attr">xmlns:xsi</span>=<span class="string">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span></span><br><span class="line"><span class="tag">         <span class="attr">xsi:schemaLocation</span>=<span class="string">&quot;http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd&quot;</span></span></span><br><span class="line"><span class="tag">         <span class="attr">version</span>=<span class="string">&quot;4.0&quot;</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!-- servlet标签给Tomcat配置Servlet程序 --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">servlet</span>&gt;</span></span><br><span class="line">        <span class="comment">&lt;!--servlet-name标签 Servlet程序起一个别名（一般是类名） --&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">servlet-name</span>&gt;</span>HelloServlet<span class="tag">&lt;/<span class="name">servlet-name</span>&gt;</span></span><br><span class="line">        <span class="comment">&lt;!--servlet-class是Servlet程序的全类名--&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">servlet-class</span>&gt;</span>com.atguigu.servlet.HelloServlet<span class="tag">&lt;/<span class="name">servlet-class</span>&gt;</span></span><br><span class="line">        <span class="comment">&lt;!--init-param是初始化参数--&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">init-param</span>&gt;</span></span><br><span class="line">            <span class="comment">&lt;!--是参数名--&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">param-name</span>&gt;</span>username<span class="tag">&lt;/<span class="name">param-name</span>&gt;</span></span><br><span class="line">            <span class="comment">&lt;!--是参数值--&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">param-value</span>&gt;</span>root<span class="tag">&lt;/<span class="name">param-value</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">init-param</span>&gt;</span></span><br><span class="line">        <span class="comment">&lt;!--init-param是初始化参数--&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">init-param</span>&gt;</span></span><br><span class="line">            <span class="comment">&lt;!--是参数名--&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">param-name</span>&gt;</span>url<span class="tag">&lt;/<span class="name">param-name</span>&gt;</span></span><br><span class="line">            <span class="comment">&lt;!--是参数值--&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">param-value</span>&gt;</span>jdbc:mysql://localhost:3306/test<span class="tag">&lt;/<span class="name">param-value</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">init-param</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">servlet</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!--servlet-mapping标签给servlet程序配置访问地址--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">servlet-mapping</span>&gt;</span></span><br><span class="line">        <span class="comment">&lt;!--servlet-name标签的作用是告诉服务器，我当前配置的地址给哪个Servlet程序使用--&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">servlet-name</span>&gt;</span>HelloServlet<span class="tag">&lt;/<span class="name">servlet-name</span>&gt;</span></span><br><span class="line">        <span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">            url-pattern标签配置访问地址                                     &lt;br/&gt;</span></span><br><span class="line"><span class="comment">               / 斜杠在服务器解析的时候，表示地址为：http://ip:port/工程路径          &lt;br/&gt;</span></span><br><span class="line"><span class="comment">               /hello 表示地址为：http://ip:port/工程路径/hello              &lt;br/&gt;</span></span><br><span class="line"><span class="comment">        --&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">url-pattern</span>&gt;</span>/hello<span class="tag">&lt;/<span class="name">url-pattern</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">servlet-mapping</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">web-app</span>&gt;</span></span><br></pre></td></tr></table></figure>

<h3 id="URL到-Servlet-程序的访问"><a href="#URL到-Servlet-程序的访问" class="headerlink" title="URL到 Servlet 程序的访问"></a>URL到 Servlet 程序的访问</h3><p><img src="https://gitee.com/AD-Gai-Code/pic-go/raw/master/image-20210412111221442.png" alt="image-20210412111221442"></p>
<h3 id="Servlet-的生命周期"><a href="#Servlet-的生命周期" class="headerlink" title="Servlet 的生命周期"></a>Servlet 的生命周期</h3><p>1、执行 Servlet 构造器方法 </p>
<p>2、执行 init 初始化方法  </p>
<ul>
<li>第一、二步，是在第一次访问的时候创建 Servlet 程序会调用。 </li>
</ul>
<p>3、执行 service 方法  第三步，每次访问都会调用。 </p>
<p>4、执行 destroy 销毁方法  第四步，在 web 工程停止的时候调用</p>
<h3 id="GET-和-POST-请求的分发处理"><a href="#GET-和-POST-请求的分发处理" class="headerlink" title="GET 和 POST 请求的分发处理"></a>GET 和 POST 请求的分发处理</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.atguigu.servlet;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> javax.servlet.*;</span><br><span class="line"><span class="keyword">import</span> javax.servlet.http.HttpServletRequest;</span><br><span class="line"><span class="keyword">import</span> java.io.IOException;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">HelloServlet</span> <span class="keyword">implements</span> <span class="title">Servlet</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">HelloServlet</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;1 构造器方法&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * service方法是专门用来处理请求和响应的</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> servletRequest</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> servletResponse</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@throws</span> ServletException</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@throws</span> IOException</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">service</span><span class="params">(ServletRequest servletRequest, ServletResponse servletResponse)</span> <span class="keyword">throws</span> ServletException, IOException </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;3 service === Hello Servlet 被访问了&quot;</span>);</span><br><span class="line">        <span class="comment">// 类型转换（因为它有getMethod()方法）</span></span><br><span class="line">        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;</span><br><span class="line">        <span class="comment">// 获取请求的方式</span></span><br><span class="line">        String method = httpServletRequest.getMethod();</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (<span class="string">&quot;GET&quot;</span>.equals(method)) &#123;</span><br><span class="line">            doGet();</span><br><span class="line">        &#125; <span class="keyword">else</span> <span class="keyword">if</span> (<span class="string">&quot;POST&quot;</span>.equals(method)) &#123;</span><br><span class="line">           doPost();</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 做get请求的操作</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">doGet</span><span class="params">()</span></span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;get请求&quot;</span>);</span><br><span class="line">        System.out.println(<span class="string">&quot;get请求&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 做post请求的操作</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">doPost</span><span class="params">()</span></span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;post请求&quot;</span>);</span><br><span class="line">        System.out.println(<span class="string">&quot;post请求&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="通过继承-HttpServlet-实现-Servlet-程序"><a href="#通过继承-HttpServlet-实现-Servlet-程序" class="headerlink" title="通过继承 HttpServlet 实现 Servlet 程序"></a>通过继承 HttpServlet 实现 Servlet 程序</h3><p>一般在实际项目开发中，都是使用继承 HttpServlet 类的方式去实现 Servlet 程序。 </p>
<p>1、编写一个类去继承 HttpServlet 类 </p>
<p>2、根据业务需要重写 doGet 或 doPost 方法 </p>
<p>3、到 web.xml 中的配置 Servlet 程序的访问地址</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">HelloServlet2</span> <span class="keyword">extends</span> <span class="title">HttpServlet</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">init</span><span class="params">(ServletConfig config)</span> <span class="keyword">throws</span> ServletException </span>&#123;</span><br><span class="line">        <span class="keyword">super</span>.init(config);</span><br><span class="line">        System.out.println(<span class="string">&quot;重写了init初始化方法,做了一些工作&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * doGet（）在get请求的时候调用</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> req</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> resp</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@throws</span> ServletException</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@throws</span> IOException</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">doGet</span><span class="params">(HttpServletRequest req, HttpServletResponse resp)</span> <span class="keyword">throws</span> ServletException, IOException </span>&#123;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">int</span> i =  <span class="number">12</span> / <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">        System.out.println(<span class="string">&quot;HelloServlet2 的doGet方法&quot;</span>);</span><br><span class="line">        <span class="comment">// 也可以使用.</span></span><br><span class="line">        ServletConfig servletConfig = getServletConfig();</span><br><span class="line">        System.out.println(servletConfig);</span><br><span class="line"></span><br><span class="line">        <span class="comment">//  2、获取初始化参数init-param</span></span><br><span class="line">        System.out.println(<span class="string">&quot;初始化参数username的值是;&quot;</span> + servletConfig.getInitParameter(<span class="string">&quot;username&quot;</span>));</span><br><span class="line">        System.out.println(<span class="string">&quot;初始化参数url的值是;&quot;</span> + servletConfig.getInitParameter(<span class="string">&quot;url&quot;</span>));</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * doPost（）在post请求的时候调用</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> req</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> resp</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@throws</span> ServletException</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@throws</span> IOException</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">doPost</span><span class="params">(HttpServletRequest req, HttpServletResponse resp)</span> <span class="keyword">throws</span> ServletException, IOException </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;HelloServlet2 的doPost方法&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="Servlet类的继承体系"><a href="#Servlet类的继承体系" class="headerlink" title="Servlet类的继承体系"></a>Servlet类的继承体系</h3><p><img src="https://gitee.com/AD-Gai-Code/pic-go/raw/master/image-20210412113852585.png" alt="image-20210412113852585"></p>
<h2 id="Ⅲ-HttpServletRequest-类"><a href="#Ⅲ-HttpServletRequest-类" class="headerlink" title="Ⅲ.HttpServletRequest 类"></a>Ⅲ.HttpServletRequest 类</h2><h3 id="HttpServletRequest-类有什么作用"><a href="#HttpServletRequest-类有什么作用" class="headerlink" title="HttpServletRequest 类有什么作用"></a>HttpServletRequest 类有什么作用</h3><p>每次只要有请求进入 Tomcat 服务器，Tomcat 服务器就会把请求过来的 HTTP 协议信息解析好封装到 Request 对象中。 然后传递到 service 方法（doGet 和 doPost）中给我们使用。我们可以用HttpServletRequest 对象，获取到所有请求的 信息。</p>
<h3 id="HttpServletRequest"><a href="#HttpServletRequest" class="headerlink" title="HttpServletRequest"></a>HttpServletRequest</h3><p>i. getRequestURI()                 获取请求的资源路径 </p>
<p>ii. getRequestURL()               获取请求的统一资源定位符（绝对路径） </p>
<p>iii. getRemoteHost()               获取客户端的 ip 地址 </p>
<p>iv. getHeader()                       获取请求头 </p>
<p>v. getParameter()                   获取请求的参数 </p>
<p>vi. getParameterValues()       获取请求的参数（多个值的时候使用） </p>
<p>vii. getMethod()                      获取请求的<strong>方式</strong> GET 或 POST </p>
<p>viii. setAttribute(key, value);   设置域数据 </p>
<p>ix. getAttribute(key);              获取域数据 </p>
<p>x. getRequestDispatcher()     获取请求转发对象</p>
<h3 id="请求的转发"><a href="#请求的转发" class="headerlink" title="请求的转发"></a>请求的转发</h3><p>请求转发是指，服务器收到请求后，从一次资源跳转到另一个资源的操作叫请求转发。</p>
<p><img src="https://gitee.com/AD-Gai-Code/pic-go/raw/master/image-20210412153202697.png" alt="image-20210412153202697"></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Servlet1</span> <span class="keyword">extends</span> <span class="title">HttpServlet</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">doGet</span><span class="params">(HttpServletRequest req, HttpServletResponse resp)</span> <span class="keyword">throws</span> ServletException, IOException </span>&#123;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 获取请求的参数（办事的材料）查看</span></span><br><span class="line">        String username = req.getParameter(<span class="string">&quot;username&quot;</span>);</span><br><span class="line">        System.out.println(<span class="string">&quot;在Servlet1（柜台1）中查看参数（材料）：&quot;</span> + username);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 给材料 盖一个章，并传递到Servlet2（柜台 2）去查看</span></span><br><span class="line">        req.setAttribute(<span class="string">&quot;key1&quot;</span>,<span class="string">&quot;柜台1的章&quot;</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 问路：Servlet2（柜台 2）怎么走</span></span><br><span class="line">        <span class="comment">/**</span></span><br><span class="line"><span class="comment">         * 请求转发必须要以斜杠打头，/ 斜杠表示地址为：http://ip:port/工程名/ , 映射到IDEA代码的web目录&lt;br/&gt;</span></span><br><span class="line"><span class="comment">         *</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        RequestDispatcher requestDispatcher = req.getRequestDispatcher(<span class="string">&quot;/servlet2&quot;</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 走向Sevlet2（柜台 2）</span></span><br><span class="line">        requestDispatcher.forward(req,resp);</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Servlet2</span> <span class="keyword">extends</span> <span class="title">HttpServlet</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">doGet</span><span class="params">(HttpServletRequest req, HttpServletResponse resp)</span> <span class="keyword">throws</span> ServletException, IOException </span>&#123;</span><br><span class="line">        <span class="comment">// 获取请求的参数（办事的材料）查看</span></span><br><span class="line">        String username = req.getParameter(<span class="string">&quot;username&quot;</span>);</span><br><span class="line">        System.out.println(<span class="string">&quot;在Servlet2（柜台2）中查看参数（材料）：&quot;</span> + username);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 查看 柜台1 是否有盖章</span></span><br><span class="line">        Object key1 = req.getAttribute(<span class="string">&quot;key1&quot;</span>);</span><br><span class="line">        System.out.println(<span class="string">&quot;柜台1是否有章：&quot;</span> + key1);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 处理自己的业务</span></span><br><span class="line">        System.out.println(<span class="string">&quot;Servlet2 处理自己的业务 &quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="Ⅳ-HttpServletResponse-类"><a href="#Ⅳ-HttpServletResponse-类" class="headerlink" title="Ⅳ.HttpServletResponse 类"></a>Ⅳ.HttpServletResponse 类</h2><h3 id="HttpServletResponse-类的作用"><a href="#HttpServletResponse-类的作用" class="headerlink" title="HttpServletResponse 类的作用"></a>HttpServletResponse 类的作用</h3><p>HttpServletResponse 类和 HttpServletRequest 类一样。每次请求进来，Tomcat 服务器都会创建一个 Response 对象传 递给 Servlet 程序去使用。HttpServletRequest 表示请求过来的信息，HttpServletResponse 表示所有响应的信息， 我们如果需要设置返回给客户端的信息，都可以通过 HttpServletResponse 对象来进行设置。</p>
<h3 id="两个输出流的说明"><a href="#两个输出流的说明" class="headerlink" title="两个输出流的说明"></a>两个输出流的说明</h3><p>字节流 getOutputStream();   常用于下载（传递二进制数据） </p>
<p>字符流 getWriter();                常用于回传字符串（常用）</p>
<p>两个流同时只能使用一个。 使用了字节流，就不能再使用字符流，反之亦然，否则就会报错。</p>
<p><img src="https://gitee.com/AD-Gai-Code/pic-go/raw/master/image-20210412160221386.png" alt="image-20210412160221386"></p>
<h3 id="如何往客户端回传数据"><a href="#如何往客户端回传数据" class="headerlink" title="如何往客户端回传数据"></a>如何往客户端回传数据</h3><p>要求 ： 往客户端回传 字符串 数据</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ResponseIOServlet</span> <span class="keyword">extends</span> <span class="title">HttpServlet</span> </span>&#123;</span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">doGet</span><span class="params">(HttpServletRequest req, HttpServletResponse resp)</span> <span class="keyword">throws</span>                       ServletException,IOException </span>&#123;</span><br><span class="line">        <span class="comment">// 要求 ： 往客户端回传 字符串 数据。</span></span><br><span class="line">        PrintWriter writer = resp.getWriter();</span><br><span class="line">        writer.write(<span class="string">&quot;response&#x27;s content!!!&quot;</span>);</span><br><span class="line">   &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="响应的乱码解决"><a href="#响应的乱码解决" class="headerlink" title="响应的乱码解决"></a>响应的乱码解决</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 它会同时设置服务器和客户端都使用 UTF-8 字符集，还设置了响应头</span></span><br><span class="line"><span class="comment">// 此方法一定要在获取流对象之前调用才有效</span></span><br><span class="line">resp.setContentType(<span class="string">&quot;text/html;  charset=UTF-8&quot;</span>);</span><br></pre></td></tr></table></figure>

<h3 id="请求重定向"><a href="#请求重定向" class="headerlink" title="请求重定向"></a>请求重定向</h3><p>请求重定向，是指客户端给服务器发请求，然后服务器告诉客户端说。我给你一些地址。你去新地址访问。叫请求 重定向（因为之前的地址可能已经被废弃）。</p>
<p><img src="https://gitee.com/AD-Gai-Code/pic-go/raw/master/image-20210412160730423.png" alt="image-20210412160730423"></p>
<p>注意转发与重定向的区别，转发访问的是同一个资源，最明显的特征是浏览器地址栏的地址不会发生变化，重定向访问的是新的资源，浏览器地址栏里的地址会发生变化。</p>
<p>请求重定向的第二种方案（推荐使用）： </p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">resp.sendRedirect(<span class="string">&quot;http://localhost:8080&quot;</span>);</span><br></pre></td></tr></table></figure>

<h2 id="Ⅴ-Servlet的一些细节"><a href="#Ⅴ-Servlet的一些细节" class="headerlink" title="Ⅴ.Servlet的一些细节"></a>Ⅴ.Servlet的一些细节</h2><h3 id="1-一个已经注册的Servlet可以被多次映射"><a href="#1-一个已经注册的Servlet可以被多次映射" class="headerlink" title="1.一个已经注册的Servlet可以被多次映射"></a>1.一个已经注册的Servlet可以被多次映射</h3><p><strong>同一个Servlet可以被映射到多个URL上。</strong></p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">servlet</span>&gt;</span></span><br><span class="line">           <span class="tag">&lt;<span class="name">servlet-name</span>&gt;</span>Demo1<span class="tag">&lt;/<span class="name">servlet-name</span>&gt;</span>			            </span><br><span class="line">		   <span class="tag">&lt;<span class="name">servlet-class</span>&gt;</span>zhongfucheng.web.Demo1<span class="tag">&lt;/<span class="name">servlet-class</span>&gt;</span>       </span><br><span class="line"><span class="tag">&lt;/<span class="name">servlet</span>&gt;</span></span><br><span class="line"></span><br><span class="line">        </span><br><span class="line"><span class="tag">&lt;<span class="name">servlet-mapping</span>&gt;</span>           </span><br><span class="line">		   <span class="tag">&lt;<span class="name">servlet-name</span>&gt;</span>Demo1<span class="tag">&lt;/<span class="name">servlet-name</span>&gt;</span>            </span><br><span class="line">		   <span class="tag">&lt;<span class="name">url-pattern</span>&gt;</span>/Demo1<span class="tag">&lt;/<span class="name">url-pattern</span>&gt;</span>        </span><br><span class="line"><span class="tag">&lt;/<span class="name">servlet-mapping</span>&gt;</span></span><br><span class="line"></span><br><span class="line">        </span><br><span class="line"><span class="tag">&lt;<span class="name">servlet-mapping</span>&gt;</span>           </span><br><span class="line">		   <span class="tag">&lt;<span class="name">servlet-name</span>&gt;</span>Demo1<span class="tag">&lt;/<span class="name">servlet-name</span>&gt;</span>            </span><br><span class="line">		   <span class="tag">&lt;<span class="name">url-pattern</span>&gt;</span>/ouzicheng<span class="tag">&lt;/<span class="name">url-pattern</span>&gt;</span>        </span><br><span class="line"><span class="tag">&lt;/<span class="name">servlet-mapping</span>&gt;</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>无论访问的是<a target="_blank" rel="noopener" href="http://localhost:8080/Demo1%E8%BF%98%E6%98%AFhttp://localhost:8080/ouzicheng%E3%80%82%E8%AE%BF%E9%97%AE%E7%9A%84%E9%83%BD%E6%98%AFDemo1%E3%80%82">http://localhost:8080/Demo1还是http://localhost:8080/ouzicheng。访问的都是Demo1。</a></p>
<h3 id="2-Servlet是单例的"><a href="#2-Servlet是单例的" class="headerlink" title="2.Servlet是单例的"></a>2.Servlet是单例的</h3><h4 id="为什么Servlet是单例的"><a href="#为什么Servlet是单例的" class="headerlink" title="为什么Servlet是单例的"></a>为什么Servlet是单例的</h4><p><strong>浏览器多次对Servlet的请求</strong>，一般情况下，<strong>服务器只创建一个Servlet对象</strong>，也就是说，Servlet对象<strong>一旦创建了</strong>，就会<strong>驻留在内存中，为后续的请求做服务，直到服务器关闭</strong>。</p>
<h4 id="每次访问请求对象和响应对象都是新的"><a href="#每次访问请求对象和响应对象都是新的" class="headerlink" title="每次访问请求对象和响应对象都是新的"></a>每次访问请求对象和响应对象都是新的</h4><p>对于<strong>每次访问请求</strong>，Servlet引擎都会<strong>创建一个新的HttpServletRequest请求对象和一个新的HttpServletResponse响应对象</strong>，然后将这两<strong>个对象作为参数传递给它调用的Servlet的service()方法</strong>，<strong>service方法再根据请求方式分别调用doXXX方法</strong>。</p>
<h3 id="3-线程安全问题"><a href="#3-线程安全问题" class="headerlink" title="3.线程安全问题"></a>3.线程安全问题</h3><p>当多个用户访问Servlet的时候，<strong>服务器会为每个用户创建一个线程</strong>。<strong>当多个用户并发访问Servlet共享资源的时候就会出现线程安全问题</strong>。</p>
<p>原则：</p>
<ol>
<li>如果一个<strong>变量需要多个用户共享</strong>，则应当在访问该变量的时候，<strong>加同步机制synchronized (对象){}</strong></li>
<li>如果一个变量<strong>不需要共享</strong>，则<strong>直接在 doGet() 或者 doPost()定义</strong>.这样不会存在线程安全问题。</li>
</ol>
<h2 id="Ⅵ-ServletContext对象"><a href="#Ⅵ-ServletContext对象" class="headerlink" title="Ⅵ. ServletContext对象"></a>Ⅵ. ServletContext对象</h2><h3 id="什么是-ServletContext"><a href="#什么是-ServletContext" class="headerlink" title="什么是 ServletContext?"></a>什么是 ServletContext?</h3><p>1、ServletContext 是一个接口，它表示 Servlet 上下文对象 </p>
<p>2、一个 web 工程，只有一个 ServletContext 对象实例。 </p>
<p>3、ServletContext 对象是一个域对象。 </p>
<p>4、ServletContext 是在 web 工程部署启动的时候创建。在 web 工程停止的时候销毁。 </p>
<p>域对象，是可以像 Map 一样存取数据的对象，叫域对象。 这里的域指的是存取数据的操作范围，整个 web 工程。</p>
<p>​                   存数据                   取数据                        删除 数据 </p>
<p>Map             put()                       get()                         remove() </p>
<p>域对象    setAttribute()          getAttribute()          removeAttribute();</p>
<h3 id="ServletContext有什么用？"><a href="#ServletContext有什么用？" class="headerlink" title="ServletContext有什么用？"></a>ServletContext有什么用？</h3><ol>
<li>ServletContext既然代表着当前web站点，那么<strong>所有Servlet都共享着一个ServletContext对象</strong>，所以<strong>Servlet之间可以通过ServletContext实现通讯</strong>。</li>
<li>ServletConfig获取的是配置的是单个Servlet的参数信息，<strong>ServletContext可以获取的是配置整个web站点的参数信息</strong></li>
<li><strong>利用ServletContext读取web站点的资源文件</strong></li>
<li>实现Servlet的转发【用ServletContext转发不多，主要用request转发】</li>
</ol>
<h2 id="Ⅶ-会话技术-Cookie-和-Session"><a href="#Ⅶ-会话技术-Cookie-和-Session" class="headerlink" title="Ⅶ. 会话技术 Cookie 和 Session"></a>Ⅶ. 会话技术 Cookie 和 Session</h2><h3 id="1-为什么需要会话技术？"><a href="#1-为什么需要会话技术？" class="headerlink" title="1.为什么需要会话技术？"></a>1.为什么需要会话技术？</h3><blockquote>
<p><strong>会话是浏览器和服务器之间的多次请求和响应</strong></p>
<p>也就是说，从浏览器<strong>访问服务器开始</strong>，到<strong>访问服务器结束</strong>，<strong>浏览器关闭为止</strong>的这段时间内容产生的<strong>多次请求和响应</strong>，合起来叫做浏览器和服务器之间的一次会话</p>
</blockquote>
<p>实际上会话问题解决的还是客户端与服务器之间的通信问题，通过一些会话技术，可以将每个用户的数据以例如cookie/session的形式存储，方便以后用户访问web资源的时候使用。</p>
<blockquote>
<p>假定场景：A和B两人在某个网上购物商场登陆账号后，A买了一个HHKB的键盘，而B则购买了一把民谣吉他，这些信息都会被保存下来</p>
<p>用途是：保存账户信息，登录时询问日后是否自动登录，或者根据之前浏览，购买过的商品，分析用户喜欢什么类型的商品，做出精准推送</p>
</blockquote>
<h3 id="2-会话技术分类"><a href="#2-会话技术分类" class="headerlink" title="2. 会话技术分类"></a>2. 会话技术分类</h3><p>客户端会话技术 —— Cookie</p>
<p>服务器会话技术 —— Session</p>
<h3 id="3-Cookie"><a href="#3-Cookie" class="headerlink" title="3. Cookie"></a>3. Cookie</h3><blockquote>
<p>Cookie是由W3C组织提出，最早由netscape社区发展的一种机制</p>
</blockquote>
<ul>
<li>网页之间的<strong>交互是通过HTTP协议传输数据的，</strong>而Http协议是<strong>无状态的协议</strong>。无状态的协议是什么意思呢？<strong>一旦数据提交完后，浏览器和服务器的连接就会关闭，再次交互的时候需要重新建立新的连接</strong>。</li>
<li>服务器无法确认用户的信息，于是乎，W3C就提出了：<strong>给每一个用户都发一个通行证，无论谁访问的时候都需要携带通行证，这样服务器就可以从通行证上确认用户的信息</strong>。通行证就是Cookie.</li>
</ul>
<h4 id="如何创建Cookie"><a href="#如何创建Cookie" class="headerlink" title="如何创建Cookie"></a>如何创建Cookie</h4><p><img src="https://gitee.com/AD-Gai-Code/pic-go/raw/master/image-20210412165223986.png" alt="image-20210412165223986"></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">createCookie</span><span class="params">(HttpServletRequest req, HttpServletResponse resp)</span> <span class="keyword">throws</span> ServletException, IOException </span>&#123;</span><br><span class="line">    <span class="comment">//1 创建Cookie对象</span></span><br><span class="line">    Cookie cookie = <span class="keyword">new</span> Cookie(<span class="string">&quot;key4&quot;</span>, <span class="string">&quot;value4&quot;</span>);</span><br><span class="line">    <span class="comment">//2 通知客户端保存Cookie</span></span><br><span class="line">    resp.addCookie(cookie);</span><br><span class="line">    <span class="comment">//1 创建Cookie对象</span></span><br><span class="line">    Cookie cookie1 = <span class="keyword">new</span> Cookie(<span class="string">&quot;key5&quot;</span>, <span class="string">&quot;value5&quot;</span>);</span><br><span class="line">    <span class="comment">//2 通知客户端保存Cookie</span></span><br><span class="line">    resp.addCookie(cookie1);</span><br><span class="line"></span><br><span class="line">    resp.getWriter().write(<span class="string">&quot;Cookie创建成功&quot;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="服务器如何获取-Cookie"><a href="#服务器如何获取-Cookie" class="headerlink" title="服务器如何获取 Cookie"></a>服务器如何获取 Cookie</h4><p>服务器获取客户端的 Cookie 只需要一行代码：req.getCookies():Cookie[]</p>
<p><img src="https://gitee.com/AD-Gai-Code/pic-go/raw/master/image-20210412170344538.png" alt="image-20210412170344538"></p>
<p>Cookie 的工具类</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">CookieUtils</span> </span>&#123;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 查找指定名称的Cookie对象</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> name</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> cookies</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> Cookie <span class="title">findCookie</span><span class="params">(String name , Cookie[] cookies)</span></span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (name == <span class="keyword">null</span> || cookies == <span class="keyword">null</span> || cookies.length == <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">for</span> (Cookie cookie : cookies) &#123;</span><br><span class="line">            <span class="keyword">if</span> (name.equals(cookie.getName())) &#123;</span><br><span class="line">                <span class="keyword">return</span> cookie;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>Servlet 程序中的代码：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">getCookie</span><span class="params">(HttpServletRequest req, HttpServletResponse resp)</span> <span class="keyword">throws</span> ServletException, IOException </span>&#123;</span><br><span class="line"></span><br><span class="line">        Cookie[] cookies = req.getCookies();</span><br><span class="line"></span><br><span class="line">        <span class="keyword">for</span> (Cookie cookie : cookies) &#123;</span><br><span class="line">            <span class="comment">// getName方法返回Cookie的key（名）</span></span><br><span class="line">            <span class="comment">// getValue方法返回Cookie的value值</span></span><br><span class="line">            resp.getWriter().write(<span class="string">&quot;Cookie[&quot;</span> + cookie.getName() + <span class="string">&quot;=&quot;</span> + cookie.getValue() + <span class="string">&quot;] &lt;br/&gt;&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        Cookie iWantCookie = CookieUtils.findCookie(<span class="string">&quot;key1&quot;</span>, cookies);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 如果不等于null，说明赋过值，也就是找到了需要的Cookie</span></span><br><span class="line">        <span class="keyword">if</span> (iWantCookie != <span class="keyword">null</span>) &#123;</span><br><span class="line">            resp.getWriter().write(<span class="string">&quot;找到了需要的Cookie&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<h4 id="Cookie值的修改"><a href="#Cookie值的修改" class="headerlink" title="Cookie值的修改"></a>Cookie值的修改</h4><p>1、先查找到需要修改的 Cookie 对象 </p>
<p>2、调用 setValue()方法赋于新的 Cookie 值。 </p>
<p>3、调用 response.addCookie()通知客户端保存修改</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">updateCookie</span><span class="params">(HttpServletRequest req, HttpServletResponse resp)</span> <span class="keyword">throws</span> ServletException, IOException </span>&#123;</span><br><span class="line">    </span><br><span class="line"><span class="comment">//        方案一：</span></span><br><span class="line"><span class="comment">//        1、先创建一个要修改的同名的Cookie对象</span></span><br><span class="line"><span class="comment">//        2、在构造器，同时赋于新的Cookie值。</span></span><br><span class="line"><span class="comment">//        Cookie cookie = new Cookie(&quot;key1&quot;,&quot;newValue1&quot;);</span></span><br><span class="line"><span class="comment">//        3、调用response.addCookie( Cookie ); 通知 客户端 保存修改</span></span><br><span class="line"><span class="comment">//        resp.addCookie(cookie);</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//        方案二：</span></span><br><span class="line"><span class="comment">//        1、先查找到需要修改的Cookie对象</span></span><br><span class="line">        Cookie cookie = CookieUtils.findCookie(<span class="string">&quot;key2&quot;</span>, req.getCookies());</span><br><span class="line">        <span class="keyword">if</span> (cookie != <span class="keyword">null</span>) &#123;</span><br><span class="line"><span class="comment">//          2、调用setValue()方法赋于新的Cookie值。</span></span><br><span class="line">            cookie.setValue(<span class="string">&quot;newValue2&quot;</span>);</span><br><span class="line"><span class="comment">//          3、调用response.addCookie()通知客户端保存修改</span></span><br><span class="line">            resp.addCookie(cookie);</span><br><span class="line">        &#125;</span><br><span class="line">        resp.getWriter().write(<span class="string">&quot;key1的Cookie已经修改好&quot;</span>);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<h4 id="浏览器查看-Cookie："><a href="#浏览器查看-Cookie：" class="headerlink" title="浏览器查看 Cookie："></a>浏览器查看 Cookie：</h4><p><img src="https://gitee.com/AD-Gai-Code/pic-go/raw/master/image-20210412171712463.png" alt="image-20210412171712463"></p>
<h4 id="Cookie-生命控制"><a href="#Cookie-生命控制" class="headerlink" title="Cookie 生命控制"></a>Cookie 生命控制</h4><p>Cookie 的生命控制指的是如何管理  Cookie 什么时候被销毁（删除） </p>
<p>setMaxAge() 正数      表示在指定的秒数后过期 </p>
<p>负数                            表示浏览器一关，Cookie 就会被删除（默认值是-1） </p>
<p>零                                表示马上删除 Cookie</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">life3600</span><span class="params">(HttpServletRequest req, HttpServletResponse resp)</span> <span class="keyword">throws</span> ServletException, IOException </span>&#123;</span><br><span class="line"></span><br><span class="line">    Cookie cookie = <span class="keyword">new</span> Cookie(<span class="string">&quot;life3600&quot;</span>, <span class="string">&quot;life3600&quot;</span>);</span><br><span class="line">    cookie.setMaxAge(<span class="number">60</span> * <span class="number">60</span>); <span class="comment">// 设置Cookie一小时之后被删除。无效</span></span><br><span class="line">    resp.addCookie(cookie);</span><br><span class="line">    resp.getWriter().write(<span class="string">&quot;已经创建了一个存活一小时的Cookie&quot;</span>);</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 马上删除一个Cookie</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> req</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> resp</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@throws</span> ServletException</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@throws</span> IOException</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">deleteNow</span><span class="params">(HttpServletRequest req, HttpServletResponse resp)</span> <span class="keyword">throws</span> ServletException, IOException </span>&#123;</span><br><span class="line">    <span class="comment">// 先找到你要删除的Cookie对象</span></span><br><span class="line">    Cookie cookie = CookieUtils.findCookie(<span class="string">&quot;key4&quot;</span>, req.getCookies());</span><br><span class="line">    <span class="keyword">if</span> (cookie != <span class="keyword">null</span>) &#123;</span><br><span class="line">        <span class="comment">// 调用setMaxAge(0);</span></span><br><span class="line">        cookie.setMaxAge(<span class="number">0</span>); <span class="comment">// 表示马上删除，都不需要等待浏览器关闭</span></span><br><span class="line">        <span class="comment">// 调用response.addCookie(cookie);</span></span><br><span class="line">        resp.addCookie(cookie);</span><br><span class="line"></span><br><span class="line">        resp.getWriter().write(<span class="string">&quot;key4的Cookie已经被删除&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 默认的会话级别的Cookie</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> req</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> resp</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@throws</span> ServletException</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@throws</span> IOException</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">defaultLife</span><span class="params">(HttpServletRequest req, HttpServletResponse resp)</span> <span class="keyword">throws</span> ServletException, IOException </span>&#123;</span><br><span class="line">    Cookie cookie = <span class="keyword">new</span> Cookie(<span class="string">&quot;defalutLife&quot;</span>,<span class="string">&quot;defaultLife&quot;</span>);</span><br><span class="line">    cookie.setMaxAge(-<span class="number">1</span>);<span class="comment">//设置存活时间</span></span><br><span class="line">    resp.addCookie(cookie);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="4-Session"><a href="#4-Session" class="headerlink" title="4.Session"></a>4.Session</h3><h4 id="什么是-Session-会话"><a href="#什么是-Session-会话" class="headerlink" title="什么是 Session 会话?"></a>什么是 Session 会话?</h4><p>1、Session 就一个接口（HttpSession）。 </p>
<p>2、Session 就是会话。它是用来维护一个客户端和服务器之间关联的一种技术。 </p>
<p>3、每个客户端都有自己的一个 Session 会话。 </p>
<p>4、Session 会话中，我们经常用来保存<strong>用户登录之后</strong>的信息。</p>
<blockquote>
<p>Session 是另一种记录浏览器状态的机制。不同的是Cookie保存在浏览器中，Session保存在服务器中。用户使用浏览器访问服务器的时候，服务器把用户的信息以某种的形式记录在服务器，这就是Session</p>
</blockquote>
<h4 id="为什么要使用Session技术？"><a href="#为什么要使用Session技术？" class="headerlink" title="为什么要使用Session技术？"></a>为什么要使用Session技术？</h4><p><strong>Session比Cookie使用方便，Session可以解决Cookie解决不了的事情【Session可以存储对象，而Cookie只能存储字符串】。</strong></p>
<h4 id="如何创建-Session-和获取-id-号-是否为新）"><a href="#如何创建-Session-和获取-id-号-是否为新）" class="headerlink" title="如何创建 Session 和获取(id 号,是否为新）"></a>如何创建 Session 和获取(id 号,是否为新）</h4><p>如何创建和获取 Session。它们的 API 是一样的。 </p>
<p>request.getSession()    第一次调用是：创建 Session 会话之后调用都是：获取前面创建好的 Session 会话对象。 </p>
<p>isNew();                         判断到底是不是刚创建出来的（新的） true 表示刚创建 false 表示获取之前创建 </p>
<p>​     每个会话都有一个身份证号。也就是 ID 值。而且这个 ID 是唯一的。 </p>
<p>getId()                            得到 Session 的会话 id 值。</p>
<h4 id="Session-域数据的存取"><a href="#Session-域数据的存取" class="headerlink" title="Session 域数据的存取"></a>Session 域数据的存取</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">setAttribute</span><span class="params">(HttpServletRequest req, HttpServletResponse resp)</span>                           <span class="keyword">throws</span> ServletException, IOException </span>&#123;</span><br><span class="line">    req.getSession().setAttribute(<span class="string">&quot;key1&quot;</span>, <span class="string">&quot;value1&quot;</span>);</span><br><span class="line">    resp.getWriter().write(<span class="string">&quot;已经往Session中保存了数据&quot;</span>);</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">getAttribute</span><span class="params">(HttpServletRequest req, HttpServletResponse resp)</span> 							<span class="keyword">throws</span> ServletException, IOException </span>&#123;</span><br><span class="line">        Object attribute = req.getSession().getAttribute(<span class="string">&quot;key1&quot;</span>);</span><br><span class="line">        resp.getWriter().write(<span class="string">&quot;从Session中获取出key1的数据是：&quot;</span> + attribute);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="Session-生命周期控制"><a href="#Session-生命周期控制" class="headerlink" title="Session 生命周期控制"></a>Session 生命周期控制</h4><p>public void setMaxInactiveInterval(int interval) 设置 Session 的超时时间（以秒为单位），超过指定的时长，Session 就会被销毁。 </p>
<p>值为正数的时候，设定 Session 的超时时长。 </p>
<p>负数表示永不超时（极少使用） </p>
<p>public int getMaxInactiveInterval()    获取 Session 的超时时间 </p>
<p>public void invalidate()                      让当前 Session 会话马上超时无效。 </p>
<p>Session 默认的超时时间长为 30 分钟。 因为在 Tomcat 服务器的配置文件 web.xml中默认有以下的配置，它就表示配置了当前 Tomcat 服务器下所有的 Session 超时配置默认时长为：30 分钟。</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">session-config</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">session-timeout</span>&gt;</span>30<span class="tag">&lt;/<span class="name">session-timeout</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">session-config</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>如果说。你希望你的 web 工程，默认的 Session 的超时时长为其他时长。你可以在你自己的 web.xml 配置文件中做 以上相同的配置。就可以修改你的 web 工程所有 Seession 的默认超时时长。</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">session-config</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">session-timeout</span>&gt;</span>20<span class="tag">&lt;/<span class="name">session-timeout</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">session-config</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p><img src="https://gitee.com/AD-Gai-Code/pic-go/raw/master/image-20210412174417990.png" alt="image-20210412174417990"></p>
<h4 id="浏览器和-Session-之间关联的技术内幕"><a href="#浏览器和-Session-之间关联的技术内幕" class="headerlink" title="浏览器和 Session 之间关联的技术内幕"></a>浏览器和 Session 之间关联的技术内幕</h4><p><img src="https://gitee.com/AD-Gai-Code/pic-go/raw/master/image-20210412174537456.png" alt="image-20210412174537456"></p>
<p>问题来了：<strong>服务器是如何实现一个session为一个用户浏览器服务的？换个说法：为什么服务器能够为不同的用户浏览器提供不同session？</strong></p>
<p>HTTP协议是无状态的，<strong>Session不能依据HTTP连接来判断是否为同一个用户</strong>。于是乎：<strong>服务器向用户浏览器发送了一个名为JESSIONID的Cookie，它的值是Session的id值</strong>。其实Session依据Cookie来识别是否是同一个用户。</p>
<p>简单来说：Session <strong>之所以可以识别不同的用户，依靠的就是Cookie</strong></p>
<p>该Cookie是<strong>服务器自动颁发给浏览器的</strong>，不用我们手工创建的。<strong>该Cookie的maxAge值默认是-1，也就是说仅当前浏览器使用，不将该Cookie存在硬盘中</strong></p>
<h2 id="Ⅷ-常见面试题"><a href="#Ⅷ-常见面试题" class="headerlink" title="Ⅷ. 常见面试题"></a>Ⅷ. 常见面试题</h2><h3 id="1-Tomcat-有哪几种Connector-运行模式-优化-？"><a href="#1-Tomcat-有哪几种Connector-运行模式-优化-？" class="headerlink" title="1.Tomcat 有哪几种Connector 运行模式(优化)？"></a>1.Tomcat 有哪几种Connector 运行模式(优化)？</h3><ol>
<li>bio(blocking I/O)： <strong>传统的Java I/O操作，同步且阻塞IO。</strong></li>
<li>nio(non-blocking I/O)：<strong>JDK1.4开始支持，同步阻塞或同步非阻塞IO</strong></li>
<li>apr(Apache Portable Runtime/Apache可移植运行库)：Tomcat将以JNI的形式调用Apache HTTP服务器的核心动态链接库来处理文件读取或网络传输操作，从而大大地<strong>提高Tomcat对静态文件的处理性能</strong></li>
<li>aio（nio.2）<strong>JDK7开始支持，异步非阻塞IO</strong></li>
</ol>
<h3 id="2-Servlet生命周期"><a href="#2-Servlet生命周期" class="headerlink" title="2.Servlet生命周期"></a>2.Servlet生命周期</h3><p>Servlet生命周期可分为5个步骤</p>
<ol>
<li><strong>加载Servlet</strong>。当Tomcat第一次访问Servlet的时候，<strong>Tomcat会负责创建Servlet的实例</strong></li>
<li><strong>初始化</strong>。当Servlet被实例化后，Tomcat会<strong>调用init()方法初始化这个对象</strong></li>
<li><strong>处理服务</strong>。当浏览器<strong>访问Servlet</strong>的时候，Servlet <strong>会调用service()方法处理请求</strong></li>
<li><strong>销毁</strong>。当Tomcat关闭时或者检测到Servlet要从Tomcat删除的时候会自动调用destroy()方法，<strong>让该实例释放掉所占的资源</strong>。一个Servlet如果长时间不被使用的话，也会被Tomcat自动销毁</li>
<li><strong>卸载</strong>。当Servlet调用完destroy()方法后，等待垃圾回收。如果<strong>有需要再次使用这个Servlet，会重新调用init()方法进行初始化操作</strong>。</li>
</ol>
<p>简单总结：<strong>只要访问Servlet，service()就会被调用。init()只有第一次访问Servlet的时候才会被调用。destroy()只有在Tomcat关闭的时候才会被调用。</strong></p>
<h3 id="3-get方式和post方式有何区别"><a href="#3-get方式和post方式有何区别" class="headerlink" title="3.get方式和post方式有何区别"></a>3.get方式和post方式有何区别</h3><p>数据携带上:</p>
<ul>
<li>GET方式：在URL地址后附带的参数是有限制的，其数据容量通常不能超过1K。</li>
<li>POST方式：可以在请求的实体内容中向服务器发送数据，传送的数据量无限制。</li>
</ul>
<p>请求参数的位置上:</p>
<ul>
<li>GET方式：请求参数放在URL地址后面，以?的方式来进行拼接</li>
<li>POST方式:请求参数放在HTTP请求包中</li>
</ul>
<p>用途上:</p>
<ul>
<li><p>GET方式一般用来获取数据</p>
</li>
<li><p>POST方式一般用来提交数据</p>
</li>
<li><ul>
<li>首先是因为GET方式携带的数据量比较小，无法带过去很大的数量</li>
<li>POST方式提交的参数后台更加容易解析(使用POST方式提交的中文数据，后台也更加容易解决)</li>
<li>GET方式比POST方式要快。具体原因：<a target="_blank" rel="noopener" href="https://www.cnblogs.com/strayling/p/3580048.html">为什么GET方式比POST方式要快 ？</a></li>
</ul>
</li>
</ul>
<h3 id="4-forward和redirect的区别"><a href="#4-forward和redirect的区别" class="headerlink" title="4.forward和redirect的区别"></a>4.forward和redirect的区别</h3><ul>
<li><p><strong>实际发生位置不同，地址栏不同</strong></p>
</li>
<li><ul>
<li>转发是发生在服务器的</li>
<li><strong>转发是由服务器进行跳转的</strong>，也就是说<strong>浏览器是不知道该跳转的动作，转发是对浏览器透明的</strong>。<strong>实现转发只是一次的http请求</strong>，<strong>一次转发中request和response对象都是同一个</strong>。这也解释了为什么可以使用<strong>request作为域对象进行Servlet之间的通讯。</strong></li>
</ul>
</li>
<li><p>重定向是发生在浏览器的 - <strong>重定向是由浏览器进行跳转的</strong>，进行重定向跳转的时候，<strong>浏览器的地址会发生变化的</strong>。实现重定向的原理是由response的状态码和Location头组合而实现的。<strong>这是由浏览器进行的页面跳转</strong>实现重定向<strong>会发出两个http请求</strong>，<strong>request域对象是无效的，因为它不是同一个request对象</strong></p>
</li>
<li><p><strong>用法不同:</strong></p>
</li>
<li><p>很多人都搞不清楚转发和重定向的时候，<strong>资源地址究竟怎么写</strong>。有的时候要把应用名写上，有的时候不用把应用名写上。很容易把人搞晕。记住一个原则： <strong>给服务器用的直接从资源名开始写，给浏览器用的要把应用名写上</strong></p>
</li>
<li><ul>
<li>request.getRequestDispatcher(“/资源名 URI”).forward(request,response)</li>
<li><strong>转发时”/“代表的是本应用程序的根目录【zhongfucheng】</strong> - response.send(“/web应用/资源名 URI”); - <strong>重定向时”/“代表的是webapps目录</strong></li>
</ul>
</li>
<li><p><strong>能够去往的URL的范围不一样:</strong></p>
</li>
<li><ul>
<li><strong>转发是服务器跳转只能去往当前web应用的资源</strong></li>
<li><strong>重定向是服务器跳转，可以去往任何的资源</strong></li>
</ul>
</li>
<li><p><strong>传递数据的类型不同</strong></p>
</li>
<li><ul>
<li><strong>转发的request对象可以传递各种类型的数据，包括对象</strong></li>
<li><strong>重定向只能传递字符串</strong></li>
</ul>
</li>
<li><p><strong>跳转的时间不同</strong></p>
</li>
<li><ul>
<li><strong>转发时：执行到跳转语句时就会立刻跳转</strong></li>
<li><strong>重定向：整个页面执行完之后才执行跳转</strong></li>
</ul>
</li>
</ul>
<p>那么转发(forward)和重定向(redirect)使用哪一个？</p>
<ul>
<li>根据上面说明了转发和重定向的区别也可以很容易概括出来<strong>。转发是带着转发前的请求的参数的。重定向是新的请求</strong>。</li>
</ul>
<p>典型的应用场景：</p>
<ol>
<li>转发: 访问 Servlet 处理业务逻辑，然后 forward 到 jsp 显示处理结果，浏览器里 URL 不变</li>
<li>重定向: 提交表单，处理成功后 redirect 到另一个 jsp，防止表单重复提交，浏览器里 URL 变了</li>
</ol>
<h3 id="5-tomcat容器是如何创建servlet类实例？用到了什么原理？"><a href="#5-tomcat容器是如何创建servlet类实例？用到了什么原理？" class="headerlink" title="5.tomcat容器是如何创建servlet类实例？用到了什么原理？"></a>5.tomcat容器是如何创建servlet类实例？用到了什么原理？</h3><ol>
<li>当容器启动时，会读取在webapps目录下所有的web应用中的web.xml文件，然后对 <strong>xml文件进行解析，并读取servlet注册信息</strong>。然后，将每个应用中注册的servlet类都进行加载，并通过 <strong>反射的方式实例化</strong>。（有时候也是在第一次请求时实例化）</li>
<li>在servlet注册时加上1如果为正数，则在一开始就实例化，如果不写或为负数，则第一次请求实例化。</li>
</ol>
<h3 id="6-什么是cookie？Session和cookie有什么区别？"><a href="#6-什么是cookie？Session和cookie有什么区别？" class="headerlink" title="6.什么是cookie？Session和cookie有什么区别？"></a>6.什么是cookie？Session和cookie有什么区别？</h3><ul>
<li>网页之间的<strong>交互是通过HTTP协议传输数据的，</strong>而Http协议是<strong>无状态的协议</strong>。无状态的协议是什么意思呢？<strong>一旦数据提交完后，浏览器和服务器的连接就会关闭，再次交互的时候需要重新建立新的连接</strong>。</li>
<li>服务器无法确认用户的信息，于是乎，W3C就提出了：<strong>给每一个用户都发一个通行证，无论谁访问的时候都需要携带通行证，这样服务器就可以从通行证上确认用户的信息</strong>。通行证就是Cookie</li>
</ul>
<p>​       <strong>1. 从存储方式上比较</strong></p>
<ul>
<li><ul>
<li>Cookie只能存储字符串，如果要存储非ASCII字符串还要对其编码。</li>
<li>Session可以存储任何类型的数据，可以把Session看成是一个容器</li>
</ul>
</li>
<li><p><strong>2.从有效期上比较</strong></p>
</li>
<li><ul>
<li>Cookie保存在硬盘中，只需要设置maxAge属性为比较大的正整数，即使关闭浏览器，Cookie还是存在的</li>
<li><strong>Session的保存在服务器中，设置maxInactiveInterval属性值来确定Session的有效期。并且Session依赖于名为JSESSIONID的Cookie，该Cookie默认的maxAge属性为-1。如果关闭了浏览器，该Session虽然没有从服务器中消亡，但也就失效了。</strong></li>
</ul>
</li>
<li><p><strong>3. 从对服务器的负担比较</strong></p>
</li>
<li><ul>
<li>Session是保存在服务器的，每个用户都会产生一个Session，如果是并发访问的用户非常多，是不能使用Session的，Session会消耗大量的内存。</li>
<li>Cookie是保存在客户端的。不占用服务器的资源。像baidu、Sina这样的大型网站，一般都是使用Cookie来进行会话跟踪。</li>
</ul>
</li>
<li><p><strong>4. 从浏览器的支持上比较</strong></p>
</li>
<li><ul>
<li>如果浏览器禁用了Cookie，那么Cookie是无用的了！</li>
<li>如果浏览器禁用了Cookie，Session可以通过URL地址重写来进行会话跟踪。</li>
</ul>
</li>
<li><p><strong>5. 从跨域名上比较</strong></p>
</li>
<li><ul>
<li>Cookie可以设置domain属性来实现跨域名</li>
<li>Session只在当前的域名内有效，不可夸域名</li>
</ul>
</li>
</ul>
<p><strong>6.从隐私安全上比较</strong></p>
<ul>
<li><strong>Cookie存储在浏览器中，对客户端是可见的</strong>。信息容易泄露出去。如果使用Cookie，最好将Cookie加密</li>
<li><strong>Session存储在服务器上，对客户端是透明的</strong>。不存在敏感信息泄露问题。</li>
</ul>
<h3 id="7-Servlet安全性问题"><a href="#7-Servlet安全性问题" class="headerlink" title="7.Servlet安全性问题"></a>7.Servlet安全性问题</h3><p>由于Servlet是单例的，当多个用户访问Servlet的时候，<strong>服务器会为每个用户创建一个线程</strong>。<strong>当多个用户并发访问Servlet共享资源的时候就会出现线程安全问题</strong>。</p>
<p>原则：</p>
<ol>
<li>如果一个<strong>变量需要多个用户共享</strong>，则应当在访问该变量的时候，<strong>加同步机制synchronized (对象){}</strong></li>
<li>如果一个变量<strong>不需要共享</strong>，则<strong>直接在 doGet() 或者 doPost()定义</strong>.这样不会存在线程安全问题</li>
</ol>

    </div>

    
    
    

    <footer class="post-footer">
          <div class="post-tags">
              <a href="/tags/java%E5%9F%BA%E7%A1%80/" rel="tag"># java基础</a>
          </div>

        

          <div class="post-nav">
            <div class="post-nav-item">
                <a href="/2021/09/04/mybatis%E7%AC%94%E8%AE%B0(%E4%B8%80)/" rel="prev" title="Mybatis 学习（一）">
                  <i class="fa fa-chevron-left"></i> Mybatis 学习（一）
                </a>
            </div>
            <div class="post-nav-item">
                <a href="/2021/09/04/spring5%E6%A1%86%E6%9E%B6%E5%AD%A6%E4%B9%A0(%E4%B8%80)/" rel="next" title="Spring5框架学习系列（一）">
                  Spring5框架学习系列（一） <i class="fa fa-chevron-right"></i>
                </a>
            </div>
          </div>
    </footer>
  </article>
</div>






</div>
  </main>

  <footer class="footer">
    <div class="footer-inner">


<div class="copyright">
  &copy; 
  <span itemprop="copyrightYear">2022</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">AiLaodu</span>
</div>
  <div class="powered-by">由 <a href="https://hexo.io/" rel="noopener" target="_blank">Hexo</a> & <a href="https://theme-next.js.org/muse/" rel="noopener" target="_blank">NexT.Muse</a> 强力驱动
  </div>

    </div>
  </footer>

  
  <script src="https://cdn.jsdelivr.net/npm/animejs@3.2.1/lib/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous"></script>
<script src="/js/comments.js"></script><script src="/js/utils.js"></script><script src="/js/motion.js"></script><script src="/js/schemes/muse.js"></script><script src="/js/next-boot.js"></script>

  
<script src="https://cdn.jsdelivr.net/npm/algoliasearch@4.10.5/dist/algoliasearch-lite.umd.js" integrity="sha256-HWlivbjXc58GuU4EIZziqIE83FFZ/da42de13pGZnMA=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/instantsearch.js@4.30.2/dist/instantsearch.production.min.js" integrity="sha256-eqhx/eer5fsD7YooSb21wsfJaQkJ/4gF3bmRBZP7q2o=" crossorigin="anonymous"></script><script src="/js/third-party/search/algolia-search.js"></script>





  





</body>
</html>
